
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/soundcard.h>

// #include "srvutils/utils_sndsvr.h"
#include "utils_sndsvr.h"

const char * syntax_text =
"Sound Server Input/Output Test Utility, ver 1.0, Written by Liming Xie, Nov. 2002\n"
"Syntax: sndsvr.dbg [option]\n"
"\t-i[f]      input source, (0, 1, a.wav, etc.), f means a regular file, default is stdin.\n"
"\t-o[f]      output source, (0, 1, a.wav, etc.), f means a regular file, default is stdout.\n"
"\t-rate      sample rate, (8000, 22050, 44100, 48000, etc.), default is 48000.\n"
"\t-channel   channels, (2 for stereo, 1 for mono), default is 2.\n"
"\n"
"for example:\n"
"sndsvr.dbg -i 0 -o 0 -rate 8000 -channel 1\n"
"sndsvr.dbg -i 0 | sndsvr.dbg -o 0\n"
"sndsvr.dbg -i 0 -of ./test.wav -rate 44100\n"
"\n";

// sndsvr.dbg [-[i/o[f]] 0] [-r 8000] [-c 1]

int main( int argc, char* argv[] )
{
	int			index_in = -1, index_out = -1;
	HSNDSVR		* handle_in = NULL, * handle_out = NULL;

    int         fdin = 0, fdout = 1;
    int			in_file = 0, out_file = 0;
    int         sample_rate = 48000;
    int         channel = 2;

    int			bufsize = 1600; // 8K * 2 = 16000, so 1600 is about 1/10 second for 8K
    char		buf[ bufsize ];
    int			nread, nwrite;
    int         i, j;
    unsigned long	total_read=0, total_write=0;
    if( argc == 1 ) {
		fprintf( stderr, "Arguments required.\n" );
		fprintf( stderr, syntax_text );
		return 0;
	}

    // get arguments
    for( i=1; i<argc; i++ ) {
		if( argv[i][0] == '-' && (i+1) < argc ) {
			const char * opt = argv[ i++ ];
			switch( opt[1] ) {
			case 'i':
				if( opt[2] == 'f' ) in_file = 1;

				if( in_file ) {
					fdin = open( argv[i], O_RDONLY );
					if( fdin > 0 ) fprintf( stderr, "Open '%s' for sound input.\n", argv[i] );
					else fprintf( stderr, "Cannot open file '%s' for reading.\n", argv[i] );
				} else {
					index_in = strtol( argv[i], NULL, 0 );
				}

				break;
			case 'o':
				if( opt[2] == 'f' ) out_file = 1;

				if( out_file ) {
					fdout = open( argv[i], O_WRONLY | O_CREAT, 0666 );
					if( out_file > 0 ) fchmod( fdout, 0666 );
					if( fdout > 0 ) fprintf( stderr, "Open '%s' for sound output.\n", argv[i] );
					else fprintf( stderr, "Cannot open file '%s' for writing.\n", argv[i] );
				} else {
					index_out = strtol( argv[i], NULL, 0 );
				}

				break;
			case 'r':
				sample_rate = strtol( argv[i], NULL, 0 );
				break;
			case 'c':
				channel = strtol( argv[i], NULL, 0 );
				break;
			}
		}
	}

	// init device
	if( index_in >= 0 ) {
		handle_in = SNDSVR_open( index_in, sample_rate, channel, O_RDONLY );
		if( handle_in ) fdin = handle_in->fd;
		else fprintf( stderr, "Cannot open sound server for input with param: %d,%d,%d\n", index_in, sample_rate, channel );
	}
	if( index_out >= 0 ) {
		handle_out = SNDSVR_open( index_out, sample_rate, channel, O_WRONLY );
		if( handle_out ) fdout = handle_out->fd;
		else fprintf( stderr, "Cannot open sound server for output with param: %d,%d,%d\n", index_in, sample_rate, channel );
	}

	if( fdin >= 0 && fdout >= 0 ) {
		// okay
	} else {
		if( fdin > 2 ) close( fdin );
		if( fdout > 2 ) close( fdout );
		if( handle_in ) SNDSVR_close( handle_in );
		if( handle_out ) SNDSVR_close( handle_out );
	}

	for(;;) {
		nread = read( fdin, buf, bufsize );
		if( nread < 0 ) {
			fprintf( stderr, "Error while reading data.\n" );
			break;
		} else if ( nread == 0 ) break;
		total_read += nread;
		nwrite = write( fdout, buf, nread );
		if( nwrite != nread ) {
			fprintf( stderr, "Error while writing data.\n" );
			break;
		}
		total_write += nwrite;
	}

	if( fdin > 2 ) close( fdin );
	if( fdout > 2 ) close( fdout );

	fprintf(stderr, "Done. Total read=%lu bytes, write=%lu bytes\n"
			"Enter ^C to quit.\n",
			total_read, total_write );
	while( 1 ) sleep( 10 );

	if( handle_in ) SNDSVR_close( handle_in );
	if( handle_out ) SNDSVR_close( handle_out );

	return 0;
}
